/**
 * 
 */
package worldwind.kml.model;

import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.render.Renderable;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.InvalidParameterException;

/**
 * This class define external 3D model who may be included in a KML file.
 */
public class KML3DModel extends KMLGraphic {

	/**
	 * Specifies how altitude components in the <coordinates> element are
	 * interpreted.<br/>
	 * Default value is {@link AltitudeMode#RelativeToGround}
	 */
	private AltitudeMode altitudeMode = AltitudeMode.RelativeToGround;

	/**
	 * The mesh definition loaded as a WWJ renderable.
	 */
	private Renderable mesh;

	/**
	 * This mesh location.
	 */
	private KMLCoord location;

	/**
	 * Current sector for this model.
	 */
	private Sector sector;

	/**
	 * The mesh definition loaded as a WWJ renderable.
	 */
	public Renderable getMesh() {
		return this.mesh;
	}

	/**
	 * The mesh definition loaded as a WWJ renderable.
	 */
	public void setMesh(Renderable mesh) {
		this.mesh = mesh;
		if (this.mesh != null && this.location != null) {
			try {
				Method m = mesh.getClass().getMethod("moveTo", Position.class);
				m.invoke(this.mesh, this.location.toPosition());
			} catch (SecurityException e) {
				// no accessible
			} catch (NoSuchMethodException e) {
				// doesn't exists
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Specifies how altitude components in the <coordinates> element are
	 * interpreted.<br/>
	 * Default value is {@link AltitudeMode#RelativeToGround}
	 */
	public AltitudeMode getAltitudeMode() {
		return altitudeMode;
	}

	/**
	 * Specifies how altitude components in the <coordinates> element are
	 * interpreted.<br/>
	 * Default value is {@link AltitudeMode#RelativeToGround}
	 */
	public void setAltitudeMode(AltitudeMode mode) {
		if (mode == null)
			throw new InvalidParameterException("Altitude mode cannot be null");
		this.altitudeMode = mode;
	}

	/**
	 * This mesh location.
	 */
	public KMLCoord getLocation() {
		return this.location;
	}

	/**
	 * This mesh location.
	 */
	public void setLocation(KMLCoord coord) {
		this.location = coord;
	}

	@Override
	public Sector getSector() {
		if (sector == null) {
			// debug size
			double size = 10.0;

			double minLon = location.lon - size;
			double minLat = location.lat - size;
			double maxLon = location.lon + size;
			double maxLat = location.lat + size;

			sector = Sector.fromDegrees(minLat, maxLat, minLon, maxLon);
		}
		return sector;
	}

}
